package server

import io.circe.generic.auto._
import io.circe.syntax._
import cats.effect._
import com.comcast.ip4s._ // ip符号
import org.http4s.HttpRoutes
import org.http4s.dsl.io._
import org.http4s.implicits._
import org.http4s.ember.server._
import org.http4s.circe._
import org.typelevel.log4cats.LoggerFactory
import org.typelevel.log4cats.slf4j.Slf4jFactory
import java.sql.{Connection, DriverManager, ResultSet}



case class ResData(k :String, v  :Int) 

object JDBC:
  val url = "jdbc:mysql://192.168.10.101:3306/boss"
  val username = "hive"
  val pwd = "123456"
  var connection: Connection = null

  def getTableData(tableName :String) = IO {
    var lst = List[ResData]()
    try {
      connection = DriverManager.getConnection(url, username, pwd)
      val statement = connection.createStatement()
      val sql = s"select * from $tableName"
      val resSet = statement.executeQuery(sql)

      while resSet.next() do 
        lst = lst.appended(ResData(resSet.getString("k"),resSet.getInt("v")))

    } catch {
      case e: Exception => e.printStackTrace()
    } finally {
        connection.close()
    }
      lst
  }
    


def handler_sorted(apiName :String, takeNum :Int) = for {
    data <- JDBC.getTableData(apiName)
    sorted = data.sortWith(_.v > _.v).take(takeNum)
    resp <- Ok(sorted.asJson)
  } yield resp


def handler(apiName :String) = for {
    data <- JDBC.getTableData(apiName)
    resp <- Ok(data.asJson)
  } yield resp

object Main extends IOApp {

  implicit val loggerFactory: LoggerFactory[IO] = Slf4jFactory.create[IO]

  val BossZhipinService = HttpRoutes.of[IO] {
    
    case GET -> Root / "degree"  => handler("degree")
      
    case GET -> Root / "exp" => handler("exp")

    case GET -> Root / "skill" => handler_sorted("skill", 20)

    case GET -> Root / "salary" => handler_sorted("salary", 15)

  }.orNotFound

  def run(args: List[String]): IO[ExitCode] =
    EmberServerBuilder
      .default[IO]
      .withHost(ipv4"0.0.0.0")
      .withPort(port"8080")
      .withHttpApp(BossZhipinService)
      .build
      .use(_ => IO.never)
      .as(ExitCode.Success)
}
